﻿#region Using Directives

    using System;
    using System.Linq;
    using System.Text;

    using Csla;
    using Csla.Data;
    using Csla.Reflection;
    using Csla.Server;

    using MarketPulse.BusinessLogic.Private;

    using MarketPulse.DataAccess.DataContextObjects.Production;

#endregion

namespace MarketPulse.DataAccess.Factory
{
    /// <summary>
    /// Abstracts the creation of a response away from the Reponse object itself
    /// </summary>
    public class ResponseFactory : ObjectFactory
    {
        #region Member Variables

            /// <summary>
            /// Property that stores the name of the class.
            /// </summary>
            private static readonly Type mClass = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;

            /// <summary>
            /// Property that stores the log4net logger for this class.
            /// </summary>
            private static readonly log4net.ILog mLog = log4net.LogManager.GetLogger(mClass);

        #endregion

        #region Methods

            #region Create Methods

                /// <summary>
                /// Method used to create and return a new Response object instance
                /// Response is intended to be a child of a Visit and so delegates
                /// responsibility for its persistence to the Visit ObjectFactory
                /// implementation.
                /// </summary>
                /// <returns>The newly created Response object</returns>
                public BusinessLogic.Private.Response Create()
                {
                    // Create a new instance of the object
                    var response = (BusinessLogic.Private.Response)MethodCaller.CreateInstance(typeof(BusinessLogic.Private.Response));

                    response.Obsolete = false;

                    // Mark it as a new object
                    MarkNew(response);
                    CheckRules(response);

                    return response;
                }

            #endregion

            #region Fetch Methods

                /// <summary>
                /// Method used to fetch a Response object from the database.
                /// </summary>
                /// <param name="criteria">The criteria object holding the Guid of the Response to retrieve</param>
                /// <returns>The Response object obtained from the database.</returns>
                public BusinessLogic.Private.Response Fetch(SingleCriteria<Guid> criteria)
                {
                    try
                    {
                        using (var manager = ContextManager<MUM_dev>.GetManager(Database.BusinessSystem))
                        {
                            var response = (BusinessLogic.Private.Response)MethodCaller.CreateInstance(typeof(BusinessLogic.Private.Response));

                            var selectResult = manager.DataContext.UspResponseSelect(criteria.Value);

                            // Get the result
                            UspResponseSelectResult result = null;
                            try
                            {
                                result = selectResult.Single();
                            }
                            catch (InvalidOperationException ioe)
                            {
                                // Construct error message
                                StringBuilder errorMessage = new StringBuilder();
                                errorMessage.Append("Unable to locate exactly one Response with Guid = [ ");
                                errorMessage.Append(criteria.Value);
                                errorMessage.Append(" ]");
                                mLog.Error(errorMessage.ToString(), ioe);
                                throw new DataAccessException(errorMessage.ToString());
                            }

                            // Common properties inherited from MarketPulseBase<Visit>
                            LoadProperty(response, BusinessLogic.Private.Response.GUIDProperty, criteria.Value);
                            LoadProperty(response, BusinessLogic.Private.Response.ObsoleteProperty, result.Obsolete.Value);
                            LoadProperty(response, BusinessLogic.Private.Response.InsertDateTimeProperty, result.InsertDateTime.Value);
                            LoadProperty(response, BusinessLogic.Private.Response.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                            LoadProperty(response, BusinessLogic.Private.Response.UpdateDateTimeProperty, result.UpdateDateTime.Value);
                            LoadProperty(response, BusinessLogic.Private.Response.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                            // Other properties                    
                            //LoadProperty(target, BusinessObjects.Response., source.SurveyVersionID.Value);                    
                            LoadProperty(response, BusinessLogic.Private.Response.mResponseXMLProperty, result.ResponseXML.ToString());

                            // Make sure that CSLA knows this has changed since being instantiated
                            MarkOld(response);
                            return response;
                        }
                    }
                    catch (DataAccessException dae)
                    {
                        mLog.Error(dae.ToString());
                        throw dae;
                    }
                    catch (Exception ex)
                    {
                        mLog.Error(ex.ToString());
                        throw ex;
                    }
                }

            #endregion        

        #endregion                      
 
    }
}
